from abc import ABC, abstractmethod
from typing import Iterator, List, Dict, Any, Optional, Tuple as TupleType
# 将第3行的相对导入改为绝对导入
from src.catalog.table_manager import TableManager

class Schema:
    """表结构描述类
    
    简单的Schema实现，包含字段列表
    """
    
    def __init__(self, fields: List[TupleType[str, str]]):
        """初始化Schema
        
        Args:
            fields: 字段列表，每个元素为(字段名, 字段类型)的元组
        """
        self.fields = fields  # [(field_name, field_type), ...]
        self.column_names = [field[0] for field in fields]
        self.column_types = [field[1] for field in fields]

    def get_field_count(self) -> int:
        """获取字段数量"""
        return len(self.fields)
    
    def get_field_name(self, index: int) -> str:
        """根据索引获取字段名"""
        return self.fields[index][0]
    
    def get_field_type(self, index: int) -> str:
        """根据索引获取字段类型"""
        return self.fields[index][1]
    
    def get_field_index(self, field_name: str) -> int:
        """根据字段名获取索引"""
        for i, (name, _) in enumerate(self.fields):
            if name == field_name:
                return i
        return -1

class ExecutionContext:
    """执行上下文"""
    
    def __init__(self, tm: Any = None,xid:int = None) -> None:
        self.table_manager = tm
        self.transaction_id = xid
        self.indexes: Dict[str, Any] = {}

    def get_table_manager(self) -> "TableManager":
        return self.table_manager
    
    def get_table(self, table_name: str):
        """通过table_manager获取表对象"""
        if not self.table_manager:
            return None
        return self.table_manager.get_table(table_name)
    
    def get_table_schema(self, table_name: str):
        if not self.table_manager:
            return []
        return self.table_manager.get_table_schema(table_name)
    
    def create_table(self, table_name: str, fields: List[Any]):
        """创建表"""
        if not self.table_manager:
            raise RuntimeError("No TableManager bound to ExecutionContext")
        return self.table_manager.create_table(table_name, fields)
    
    def add_index(self, table_name: str, index_name: str, btree_index):
        """添加索引"""
        if table_name not in self.indexes:
            self.indexes[table_name] = {}
        self.indexes[table_name][index_name] = btree_index

    def get_index(self, table_name: str, index_name: str):
        """获取索引"""
        return self.indexes.get(table_name, {}).get(index_name)

class Tuple:
    """元组"""
    
    def __init__(self, schema: Schema, values: List[Any]):
        print("schema:", schema)
        print("values:", values)
        if len(values) != schema.get_field_count():
            raise ValueError("Tuple length does not match schema field count")
        self.schema = schema
        self.values = values
    
    def get_value(self, index: int) -> Any:
        return self.values[index]
    
    def get_values(self) -> List[Any]:
        return self.values

    def to_dict(self) -> Dict[str, Any]:
        """将元组对象转换为字典，键为列名，值为数据。"""
        return {self.schema.get_field_name(i): self.values[i] for i in range(self.schema.get_field_count())}

class AbstractExecutor(ABC):
    """抽象执行器"""

    def __init__(self, context: ExecutionContext,schema: Schema):
        self.context = context
        self.schema = schema
    
    @abstractmethod
    def init(self) -> None:
        """初始化执行器"""
        pass
    
    @abstractmethod
    def next(self) -> Optional[Tuple]:
        """获取下一个元组"""
        pass
    
    def __iter__(self) -> Iterator[Tuple]:
        """迭代器接口"""
        self.init()
        while True:
            tuple_result = self.next()
            if tuple_result is None:
                break
            yield tuple_result

    def get_output_schema(self) -> Schema:
        """获取输出模式"""
        return self.schema